package leetcode每日一题.leetcode20213;

/**
 * 1. 问题描述
 *      颠倒给定的 32 位无符号整数的二进制位。
 *
 * 2. 算法分析
 *     所谓的按位取反的含义：二进制的每一位上1变为0,0变为1
 *     具体的例子：0010 0101  --->  1101 1010
 *
 *     1. 按位取反
 *          设置一个掩码mask = 1，通过mask与当前数字n进行&运算获取当前n中的最低位元素，然后在于0做或运算
 *
 *          从下面的具体例子来分析问题：
 *              n = 0010  0101     mask = 0000 0001
 *              if n & mask = 1   则n当前的最低位为1
 *              if n & mask = 0   则n当前的最低位为0，这样就取出了当前n的最低位二进制上的元素
 *              然后让mask进行左移一位，mask <<= 1,此时mask = 0000 0010,重复上述的步骤即可
 * 3. 代码实现
 */
@SuppressWarnings("all")
public class Q003_2_二进制数取反 {

    /**
     * 按位取法即可，设置一个掩码 mask = 1，每次通过mask与n的&运算获取当前的最低位，然后让掩码左移一位即可
     * 每获取一位n向右移动一位，mask向左移动一位，res向左移动一位
     * @param n
     * @return
     */
    public int reverseBits1(int n) {
        int res = 0;
        int mask = 1;
        for (int i = 0; i < 32; i++) {
            res = res <<= 1;
            res |= (n & mask);
            n = n >> 1; // 由于n取走了最低位，所以n需要向右移动一位 0011 ---> 0001(自动补成4个一组的二进制)
        }
        return res;
    }

    public static void main(String[] args) {
        int reverse = Integer.reverse(10);
        System.out.println(reverse);
    }
}
